#ifndef __UTILS_H__
#define __UTILS_H__

#include <mpi.h>
#include <pthread.h>

#define NUM_CORES	4
#define MAX_LEN_NUM	8
#define MAT_A	1
#define MAT_B	2
#define BLK_SIZE	4192

struct MPI_Info_t {
	int num_procs;
	int proc_id;
	MPI_Comm* comms;
	MPI_Group* group;
};

struct algorithm_data {
	struct matrix_t* a;
	struct matrix_t* b;
	struct matrix_t* c;
	struct MPI_Info_t* info;
};

struct matrix_t {
	long* mat;
	long m, n;
};

int alloc_matrix(struct matrix_t** mat, long m, long n);
int alloc_matrix_b(struct matrix_t** mat, long m, long n);
int dealloc_matrix(struct matrix_t* mat);
int get_matrix_dim(MPI_File f, struct matrix_t** dim);
int read_matrix(
	char* filename, 
	struct matrix_t** mat, 
	struct MPI_Info_t* info, 
	int mat_id);
long get_elem(struct matrix_t* mat, long i, long j);
long get_elem_b(struct matrix_t* mat, long i, long j);
int set_elem(struct matrix_t* mat, long i, long j, long val);
int set_elem_b(struct matrix_t* mat, long i, long j, long val);
int sub_matrix(
	struct matrix_t* mat, 
	struct matrix_t** tmat, 
	long i1, long i2,
	long j1, long j2);

int mac(long* a, long* b, long n, long* ans);
int mat_prod(
	struct matrix_t* a, 
	struct matrix_t* b, 
	long i, long j, 
	long* ans);
int diag_calc(struct algorithm_data* info);
int calc(struct algorithm_data* info, struct matrix_t* b, int serverpid);

int get_mpi_info(struct MPI_Info_t* info);


#endif
